/*----------------------------------------------------------------------------------------
*
*  Copyright 2019, Gao Hai Hui, <fromzeropoint@126.com>.  All rights reserved.
*  https://gitee.com/helloworldghh/xoskit.git
*  Use of this source code is governed by a MIT license
*  that can be found in the License file.
*
----------------------------------------------------------------------------------------*/
#include "../import/head.h"
#include "../impl/mgr.h"
#include "url_encode.h"

////////////////////////////////////////////////////////////////////////////////////////////////////////

namespace xos_common
{
    // 
    //1.数字和字母不变
    //2.空格变成+
    //3.其它变成%XX
    // 
    int url_encode( const char * lpszSrc, int nSrcLen, char * lpszDst, int nCharNum )
    {
        int nRet = 0;

        size_t tLen = nSrcLen;
        int nPos = 0;

        for( size_t ix = 0; ix < tLen; ix++ )
        {
            unsigned char uc = ( unsigned char )lpszSrc[ix];

            if( isalnum( uc ) )
            {       
                lpszDst[nPos] = lpszSrc[ix];
                ++nPos;
            }
            else if( isspace( uc ) )
            {
                lpszDst[nPos] = '+';
                ++nPos;
            }
            else
            {
                mgr::container()->crt()->sprintf( lpszDst + nPos, nCharNum - nPos, "%%%02x", uc );
                nPos += 3;
            }
        }

        if( 0 == nRet )
        {
            lpszDst[nPos] = 0;
        }

        return nRet;
    }

    int url_decode( const char * lpszSrc, int nSrcLen, char * lpszDst, int nCharNum )
    {
        int nRet = 0;

        int nLen = nSrcLen;
        int nPos = 0;

        for( int i = 0; i < nLen; )
        {
            unsigned char uc = ( unsigned char )lpszSrc[i];

            if( '+' == uc )
            {
                lpszDst[nPos] = ' ';
                ++nPos;
                i++;
            }
            else if( '%' == uc )
            {
                i++; // 跳过%

                unsigned char c1 = 0;
                unsigned char c2 = 0;

                hex_to_dec( c1, lpszSrc[i] );
                hex_to_dec( c2, lpszSrc[i+1] );

                lpszDst[nPos] = ( char )( c1 << 4 | c2 );
                nPos++;
                i += 2;
            }
            else
            {
                lpszDst[nPos] = lpszSrc[i];
                ++nPos;
                i++;
            }

            if( nCharNum < nPos + 3 )
            {
                nRet = 1;
                break;
            }
        }

        if( nPos < nCharNum )
        {
            lpszDst[nPos] = 0;
        }

        return nRet;
    }

    int hex_to_dec( unsigned char & cDec, char cHex )
    {
        int nRet = 0;

        unsigned char c = ( unsigned char )cHex;

        if( ( c >= '0' ) && ( c <= '9' ) )
        {
            cDec = c - 48;
        }
        else if( ( c >= 'A' ) && ( c <= 'F' ) )
        {
            cDec = c - 'A' + 10;
        }
        else if( ( c >= 'a' ) && ( c <= 'f' ) )
        {
            cDec = c - 'a' + 10;
        }

        return nRet;
    }

    int dec_to_hex( unsigned char cDec, char & cHex )
    {
        int nRet = 0;

        if( cDec <= 9 )
        {
            cHex = '0' + cDec;
        }
        else if( ( cDec >= 'A' ) && ( cDec <= 'F' ) )
        {
            cHex = 'A' + cDec - 10;
        }
        else if( ( cDec >= 'a' ) && ( cDec <= 'f' ) )
        {
            cHex = 'a' + cDec - 10;
        }

        return nRet;
    }

} // xos_common
